/***************************************************************************
 *   Copyright (c) 2017 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "pch.h"




#include "Gui/Application.h"


#include <App/Document.h>
#include "SoFCCSysDragger.h"
#include "SoFCUnifiedSelection.h"

#include "View3DInventorViewer.h"
#include "ViewProviderDragger.h"
#include <Gui/Document.h>

using namespace Gui;

PROPERTY_SOURCE(Gui::ViewProviderDragger, Gui::ViewProviderDocumentObject)

ViewProviderDragger::ViewProviderDragger()
{
}

ViewProviderDragger::~ViewProviderDragger()
{
}

void ViewProviderDragger::updateData(const App::Property* prop)
{
    if (prop->isDerivedFrom(App::PropertyPlacement::getClassTypeId()) &&
        strcmp(prop->getName(), "Placement") == 0) {
        // Note: If R is the rotation, c the rotation center and t the translation
        // vector then Inventor applies the following transformation: R*(x-c)+c+t
        // In FreeCAD a placement only has a rotation and a translation part but
        // no rotation center. This means that the following equation must be ful-
        // filled: R * (x-c) + c + t = R * x + t
        //    <==> R * x + t - R * c + c = R * x + t
        //    <==> (I-R) * c = 0 ==> c = 0
        // This means that the center point must be the origin!
        Base::Placement p = static_cast<const App::PropertyPlacement*>(prop)->getValue();
        updateTransform(p, pcTransform);
    }

    ViewProviderDocumentObject::updateData(prop);
}
bool ViewProviderDragger::doubleClicked()
{
    Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default);
    return true;
}

void ViewProviderDragger::setupContextMenu(QMenu* menu, QObject* receiver, const char* member){}

ViewProvider *ViewProviderDragger::startEditing(int mode) {
    _linkDragger = nullptr;
    auto ret = ViewProviderDocumentObject::startEditing(mode);
    if(!ret)
        return ret;
    return _linkDragger?_linkDragger:ret;
}

bool ViewProviderDragger::checkLink(){return 0;}

bool ViewProviderDragger::setEdit(int ModNum){return 0;}

void ViewProviderDragger::unsetEdit(int ModNum){return ;}

void ViewProviderDragger::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum){return ;}

void ViewProviderDragger::unsetEditViewer(Gui::View3DInventorViewer* viewer)
{
  SoFCUnifiedSelection* selection = static_cast<SoFCUnifiedSelection*>(viewer->getSceneGraph());
  SoNode *child = selection->getChild(0);
  if (child && child->isOfType(SoPickStyle::getClassTypeId())) {
    selection->removeChild(child);
    selection->selectionRole.setValue(true);
  }
}

void ViewProviderDragger::dragStartCallback(void *, SoDragger *)
{
    // This is called when a manipulator is about to manipulating
    Gui::Application::Instance->activeDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Transform"));
}

void ViewProviderDragger::dragFinishCallback(void *data, SoDragger *d)
{
    // This is called when a manipulator has done manipulating

    ViewProviderDragger* sudoThis = reinterpret_cast<ViewProviderDragger *>(data);
    SoFCCSysDragger *dragger = static_cast<SoFCCSysDragger *>(d);
    updatePlacementFromDragger(sudoThis, dragger);

    Gui::Application::Instance->activeDocument()->commitCommand();
}

void ViewProviderDragger::updatePlacementFromDragger(ViewProviderDragger* sudoThis, SoFCCSysDragger* draggerIn){return ;}

void ViewProviderDragger::updateTransform(const Base::Placement& from, SoTransform* to)
{
  float q0 = (float)from.getRotation().getValue()[0];
  float q1 = (float)from.getRotation().getValue()[1];
  float q2 = (float)from.getRotation().getValue()[2];
  float q3 = (float)from.getRotation().getValue()[3];
  float px = (float)from.getPosition().x;
  float py = (float)from.getPosition().y;
  float pz = (float)from.getPosition().z;
  to->rotation.setValue(q0,q1,q2,q3);
  to->translation.setValue(px,py,pz);
  to->center.setValue(0.0f,0.0f,0.0f);
  to->scaleFactor.setValue(1.0f,1.0f,1.0f);
}
